﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Takkou.Language
{
    public interface LogicExpression
    {
        bool get();
    }

    public class ANDLogicExpression : LogicExpression
    {
        public LogicExpression E1 { get; private set; }
        public LogicExpression E2 { get; private set; }

        public ANDLogicExpression(LogicExpression e1, LogicExpression e2)
        {
            E1 = e1;
            E2 = e2;
        }

        public bool get()
        {
            return E1.get() && E2.get();
        }
    }

    public class ORLogicExpression : LogicExpression
    {
        public LogicExpression E1 { get; private set; }
        public LogicExpression E2 { get; private set; }

        public ORLogicExpression(LogicExpression e1, LogicExpression e2)
        {
            E1 = e1;
            E2 = e2;
        }

        public bool get()
        {
            return E1.get() || E2.get();
        }
    }

    public class NOTLogicExpression : LogicExpression
    {
        public LogicExpression E { get; private set; }

        public NOTLogicExpression(LogicExpression e)
        {
            E = e;
        }

        public bool get()
        {
            return !E.get();
        }
    }

    public class NumberLogicalExpression : LogicExpression
    {
        public enum OperType
        {
            EQUALS,
            NOT_EQUALS,
            LESS,
            LESS_OR_EQUALS,
            GREATER,
            GREATER_OR_EQUALS,
        }

        public Number N1 { get; private set; }
        public Number N2 { get; private set; }
        public OperType Operation { get; private set; }

        public NumberLogicalExpression(OperType operation, Number n1, Number n2)
        {
            N1 = n1;
            N2 = n2;
            Operation = operation;
        }

        public bool get()
        {
            switch (Operation)
            {
                case OperType.EQUALS:
                    return N1.get() == N2.get();
                case OperType.NOT_EQUALS:
                    return N1.get() != N2.get();
                case OperType.LESS:
                    return N1.get() < N2.get();
                case OperType.LESS_OR_EQUALS:
                    return N1.get() <= N2.get();
                case OperType.GREATER:
                    return N1.get() > N2.get();
                case OperType.GREATER_OR_EQUALS:
                    return N1.get() >= N2.get();
            }
            // TODO throw an exception
            return false;
        }
    }

    public class StringLogicalExpression : LogicExpression
    {
        public enum OperType
        {
            EQUALS,
            NOT_EQUALS,
        }

        public String S1 { get; private set; }
        public String S2 { get; private set; }
        public OperType Operation { get; private set; }

        public StringLogicalExpression(OperType operation, String s1, String s2)
        {
            S1 = s1;
            S2 = s2;
            Operation = operation;
        }

        public bool get()
        {
            switch (Operation)
            {
                case OperType.EQUALS:
                    return S1.get() == S2.get();
                case OperType.NOT_EQUALS:
                    return S1.get() != S2.get();
            }
            // TODO throw an exception
            return false;
        }
    }
}
